package org.cybzacg.convert.converters.date;


import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

/**
 * Year转换器
 * 专门处理Year类型的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(
    name = "YearConverter",
    priority = ConversionPriority.MEDIUM_HIGH,
    description = "Year类型转换器，处理各种类型到java.time.Year的转换",
    enabled = true,
    version = "4.0",
    author = "cybzacg.blog",
    supportedTypes = {Year.class},
    tags = {"year", "time", "conversion"}
)
public class YearConverter extends AbstractDateTimeConverter<Year> {

    public YearConverter() {
        super(Year.class, ConversionPriority.MEDIUM_HIGH);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.YEAR;
    }

    @Override
    protected Year parseFromString(String str, DateTimeFormatter formatter) throws DateTimeParseException {
        // 先尝试直接解析为年份数字
        try {
            return Year.of(Integer.parseInt(str));
        } catch (NumberFormatException e) {
            // 不是纯数字，尝试日期格式
        }

        // 尝试解析为LocalDate然后提取年份
        try {
            LocalDate date = LocalDate.parse(str, formatter);
            return Year.from(date);
        } catch (DateTimeParseException e) {
            // 尝试解析为LocalDateTime然后提取年份
            LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
            return Year.from(dateTime);
        }
    }

    @Override
    protected Year convertFromInstant(Instant instant, ConversionContext context) {
        return Year.from(instant.atZone(DEFAULT_ZONE_ID).toLocalDate());
    }

    @Override
    protected Year convertFromNumber(Number source, ConversionContext context) {
        int year = source.intValue();
        
        // 检查年份范围
        if (year < Year.MIN_VALUE || year > Year.MAX_VALUE) {
            throw new org.cybzacg.convert.exception.ConversionException(
                org.cybzacg.convert.enums.ConversionError.NUMBER_OVERFLOW,
                "年份超出有效范围: " + year);
        }
        
        return Year.of(year);
    }

    @Override
    protected String[] getSupportedPatterns() {
        // 合并日期和日期时间格式
        String[] datePatterns = org.cybzacg.convert.constants.DateFormats.DATE_FORMAT_PATTERNS;
        String[] datetimePatterns = org.cybzacg.convert.constants.DateFormats.DATETIME_FORMAT_PATTERNS;
        
        String[] allPatterns = new String[datePatterns.length + datetimePatterns.length];
        System.arraycopy(datePatterns, 0, allPatterns, 0, datePatterns.length);
        System.arraycopy(datetimePatterns, 0, allPatterns, datePatterns.length, datetimePatterns.length);
        
        return allPatterns;
    }

    @Override
    protected Year convertFromOtherDateTime(Object source, ConversionContext context) {
        // LocalDateTime转换
        if (source instanceof LocalDateTime localDateTime) {
            return Year.from(localDateTime);
        }

        // ZonedDateTime转换
        if (source instanceof ZonedDateTime zonedDateTime) {
            return Year.from(zonedDateTime);
        }

        // LocalDate转换
        if (source instanceof LocalDate localDate) {
            return Year.from(localDate);
        }

        // YearMonth转换
        if (source instanceof YearMonth yearMonth) {
            return Year.from(yearMonth);
        }

        return null;
    }

    @Override
    protected Year getDefaultValue() {
        return org.cybzacg.convert.constants.DateTimeDefaults.YEAR_DEFAULT;
    }
}
